home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n07.arc / ENCORE.ARC / ENCORE.ASM next >
Assembly Source File  |  1991-03-27  |  21KB  |  746 lines

  1.  
  2. ;Portions of this code are copyrighted 1990
  3. ;by RSE Incorporated and used with permission
  4.  
  5. Code        segment byte public 'code'
  6.             assume cs:code
  7.             assume ds:code
  8.  
  9. org 100h
  10. LGo: jmp Init
  11.  
  12. BoostDelay  dw      18      ;# of clock ticks (18.2/sec)
  13. BufSize     dw      500     ;buffer size in bytes (5 per keystroke)
  14. CapSS       db      4       ;1=RShft 2=LShft 4=Ctrl 8=Alt 12=Ctrl-Alt
  15. CapSC       db      19      ;Ctrl-R record hot key
  16. RepSS       db      4
  17. RepSC       db      25      ;Ctrl-P playback hot key
  18. Delay       dw      0       ;clock ticks since last key press
  19. EndBuff     dw      0       ;offset of end of buffer
  20. Pntr        dw      offset Buffer   ;offset where next key info goes
  21. Cap?        db      0       ;capture flag
  22. UpperLimit  dw      0
  23. Shift       db      0       ;shift value of key
  24. Waet        dw      0       ;keystroke delay
  25. Key         dw      0       ;ASCII and Scan Code of key
  26. KeyBufEnd   dw      0       ;end of BIOS key buffer
  27. Replay?     db      0       ;replay flag
  28. Tick        dw      0       ;keeps track of clock in sound proc
  29. Remove?     db      0       ;indicates if key press or release
  30. Message     db      'EncoreHere'
  31. BuffOff     dw      offset StrBytes
  32. BufSizOff   dw      offset BufSize
  33. Vec9        dd      0       ;Int 9 original vector
  34. Vec1C       dd      0       ;Int 1C original vector
  35.     
  36. I9          proc
  37. ;activated anytime a key is pressed OR released
  38.             sti
  39.             push    ax
  40.             push    es
  41.             mov     ax,40h
  42.             mov     es,ax
  43.             mov     ah,es:17h       ;put shift state in ah
  44.             pop     es
  45.             and     ah,0Fh          ;just want shift states
  46.  
  47.             in      al,60h          ;get scan code of key press
  48.             and     al,7Fh          ;mask out release bit
  49.             
  50. I92:        cmp     al,cs:CapSC     ;Record hot key scan code?
  51.             jne     I93
  52.             jmp     CapKey?                        
  53.  
  54. I93:        cmp     al,cs:RepSC     ;playback hot key scan code?
  55.             jne     I94
  56.             jmp     ReplayKey?
  57.  
  58. I94:        cmp     cs:Replay?,1    
  59.             jne     I95
  60.  
  61.             cmp     al,1            ;Escape pressed during Replay?
  62.             jne     I95
  63.  
  64.             call    EndReplay
  65.             mov     cs:Remove?,1    ;I9end will changes this to 0
  66.  
  67. I945:       call    I9end
  68.             pop     ax
  69.             iret
  70.  
  71. I95:        cli
  72.             pushf
  73.             call    cs:Vec9         ;call originial interupt
  74.             cmp     cs:Cap?,1
  75.             je      Capture
  76.  
  77. I96:        pop     ax
  78.             iret
  79.  
  80. ;capturing - done after Vec9 is called
  81. Capture:    push    es
  82.  
  83.             mov     ax,40h
  84.             mov     es,ax
  85.             mov     ax,es:1Ch
  86.             cmp     ax,cs:KeyBufEnd
  87.             jne     I97
  88.  
  89. ;if tail of buffer hasn't changed (no new keys) then return
  90.             pop     es
  91.             pop     ax
  92.             iret
  93.  
  94. I97:        mov     cs:KeyBufEnd,ax
  95.             push    di
  96.             push    bx
  97.             
  98.             mov     di,cs:Pntr
  99.  
  100. ;if key buffer is full then turn off capture
  101.             cmp     di,cs:UpperLimit
  102.             jb      I98
  103.             call    EndCap
  104.             jmp     I9a
  105.  
  106. ;save key info
  107. ;format - first byte=ASCII, 2=Scan Code, 3=Shift state, 4&5=Delay 
  108. I98:        add     cs:Pntr,5
  109.             mov     ax,cs:Delay
  110.             mov     cs:[di+3],ax  ;delay
  111.             mov     cs:Delay,0
  112.  
  113. ;get last key put into buffer (end of buffer-2)
  114.             mov     ax,40h
  115.             mov     es,ax
  116.             mov     bx,es:1Ch     ;end of BIOS buffer
  117.             cmp     bx,1Eh        ;remember, it's a circular buffer
  118.             jne     I99
  119.             mov     bx,3Eh
  120. I99:        dec     bx
  121.             dec     bx
  122.             mov     ax,es:[bx]
  123.             mov     cs:[di],ax    ;ASCII (al) Scan Code (ah)
  124.             mov     al,es:17h     ;shift state
  125.             mov     cs:[di+2],al  
  126.  
  127. I9a:        pop     bx
  128.             pop     di
  129.             pop     es
  130.             pop     ax
  131.             cli
  132.             iret
  133.  
  134. ;Replay hot key pressed?
  135. ReplayKey?: cmp     cs:Remove?,1
  136.             je      R20
  137.             cmp     ah,cs:RepSS 
  138.             je      R1
  139.             jmp     I94
  140.  
  141. ;initiate replay
  142. R1:         cmp     cs:Cap?,1
  143.             jne     R2
  144.  
  145. ;quit capturing before initiating replay
  146.             call    EndCap
  147.  
  148. R2:         mov     cs:Pntr,offset Buffer
  149.             cmp     cs:StrBytes,0
  150.             ja      R21
  151.  
  152. R20:        call    I9end
  153.             pop     ax
  154.             iret
  155.  
  156. R21:        push    di
  157.             push    bx
  158.             push    ds
  159.  
  160.             mov     ax,cs
  161.             mov     ds,ax
  162.  
  163. ;use size of key sequence to compute end of buffer
  164.             mov     ax,StrBytes
  165.             add     ax,offset Buffer
  166.             mov     EndBuff,ax
  167.  
  168.             call    GetVars         ;get key info
  169.  
  170.             pop     ds
  171.             pop     bx
  172.             pop     di
  173.  
  174.             call    I9end           ;clear key from keyboard
  175.             mov     cs:Delay,0      ;reset delay
  176.  
  177.             pop     ax
  178.             cli
  179.             mov     cs:Replay?,1    ;set replay flag
  180.             iret
  181.  
  182. ;capture hot key
  183. CapKey?:    cmp     cs:Remove?,1
  184.             je      R20
  185.  
  186.             cmp     ah,cs:CapSS
  187.             je      Cap1
  188.             jmp     I94
  189. ;Capture
  190. Cap1:       call    I9end
  191.             cmp     cs:Cap?,1       ;if already capturing then end
  192.             jne     Cap2
  193. ;end capture
  194.             call    EndCap
  195.             jmp     Cap3
  196.             
  197. ;starting capture
  198. Cap2:       call    sound
  199.  
  200. ;reset buffer info
  201.             mov     cs:Delay,0
  202.             mov     cs:Pntr,offset Buffer
  203.             mov     cs:Cap?,1
  204.             push    ax
  205.             mov     ax,40h
  206.             mov     es,ax
  207.             mov     ax,es:1Ch
  208.             mov     cs:KeyBufEnd,ax
  209.             pop     es
  210.  
  211. Cap3:       pop     ax
  212.             iret    
  213. I9          endp
  214.                      
  215. I9end       proc
  216.             in      al,61h    ;resets the keyboard
  217.             mov     ah,al
  218.             or      al,80h
  219.             out     61h,al
  220.             mov     al,ah
  221.             out     61h,al
  222.  
  223.             cli
  224.             mov     al,20h    ;reset interupts
  225.             out     20h,al
  226.             sti
  227.  
  228.             xor     cs:Remove?,1
  229.             ret
  230. I9end       endp
  231.  
  232. EndCap      proc              ;ends capturing
  233.             cli
  234.             mov     cs:Cap?,0
  235.             sti
  236.             call    sound
  237.             call    sound
  238.  
  239. ;anything captured?
  240.             mov     ax,cs:Pntr
  241.  
  242. ;put size of key sequence StrBytes 
  243. EC1:        mov     cs:EndBuff,ax
  244.             sub     ax,offset Buffer
  245.             mov     cs:StrBytes,ax
  246.             ret
  247. EndCap      endp
  248.  
  249. I1C         proc              ;timer interupt
  250.  
  251.             pushf
  252.             call    cs:Vec1C        ;call timer interupt
  253.  
  254.             inc     cs:Delay     
  255.             cmp     cs:Replay?,1
  256.             jae     T1
  257.             iret              ;if not replaying then we're done
  258.  
  259. ;replaying
  260. T1:         sti
  261.             push    ax
  262.             push    di
  263.             push    ds
  264.  
  265.             mov     ax,cs
  266.             mov     ds,ax
  267.  
  268.             mov     ax,Delay
  269.             cmp     ax,Waet         ;waited long enough?
  270.             jb      T4         ;return
  271.  
  272. ;put stuff in
  273.             push es
  274.             push bx
  275.  
  276.             mov     ax,40h
  277.             mov     es,ax
  278.             mov     bx,es:1Ch       ;adjust for circular buffer
  279.             cmp     bx,es:1Ah
  280.             jne     T3 
  281.  
  282.             mov     ax,Key
  283.             mov     es:[bx],ax      ;put ASCII and Scan code in
  284.             inc     bx
  285.             inc     bx
  286.             cmp     bx,3Eh
  287.             jne     T2
  288.             mov     bx,1Eh
  289. T2:         mov     es:1Ch,bx       ;adjust end of BIOS buffer
  290.             mov     al,Shift
  291.             mov     es:17h,al       ;put shift state in
  292.             push    bx
  293.             call    GetVars         ;get next key info
  294.             pop     bx
  295.  
  296. T3:         mov     Delay,0         ;reset delay
  297.             pop bx
  298.             pop es
  299.  
  300. T4:         pop ds
  301.             pop di
  302.             pop ax
  303.             iret
  304. I1C         endp
  305.  
  306. GetVars     proc
  307. ;enter with Pntr pointing to variables and ds=cs
  308. ;returns Key (ASCII and Scan Code), Shift, and Waet
  309.  
  310.             mov     di,Pntr
  311.  
  312. GV1:        mov     ax,[di]
  313.             mov     Key,ax
  314.             mov     al,[di+2]
  315.             mov     Shift,al
  316.             mov     ax,[di+3]
  317.             cmp     ax,BoostDelay   ;check if Waet <= Boost value
  318.             ja      GV3
  319. GV2:        xor     ax,ax
  320. GV3:        mov     Waet,ax
  321.  
  322.             add     di,5
  323.             mov     Pntr,di
  324.             cmp     di,EndBuff
  325.             ja      EndReplay    
  326.             ret
  327. GetVars     endp
  328.  
  329. EndReplay   proc
  330. ;terminate replay 
  331.             push    es
  332.             mov     ax,40h
  333.             mov     es,ax
  334.             mov     cs:Pntr,offset Buffer
  335.             mov     cs:Replay?,0
  336.             mov     al,es:17h       ;get shift state
  337.             and     al,0F0h         ;eliminate shifts,ctrl,alt
  338.             mov     es:17h,al       ;restore shift state
  339.             pop     es
  340.             ret
  341. EndReplay   endp
  342.  
  343. Sound       proc            ;destroys AX
  344.  
  345.             push    es
  346.  
  347.             mov     ax,40h
  348.             mov     es,ax
  349.             mov     ax,es:6Ch
  350. S1:         cmp     es:6Ch,ax
  351.             je      S1              ;wait till clock tick changes
  352.             inc     ax
  353.             mov     cs:tick,ax
  354.  
  355.             mov     al,0B6h
  356.             out     43h,al          ;get timer ready
  357.  
  358.             mov     ax,0C00h
  359.  
  360.             out     42h,al
  361.             mov     al,ah
  362.             out     42h,al          ;set freq
  363.  
  364.             in      al,61h
  365.             or      al,3
  366.             out     61h,al          ;turn speaker on
  367.  
  368.             mov     ax,cs:tick
  369. S2:         cmp     ax,es:6Ch
  370.             je      S2              ;do for one clock tick
  371.  
  372.             in      al,61h          ;turn off speaker
  373.             and     al,11111100b
  374.             out     61h,al
  375.  
  376.             pop     es
  377.             ret
  378. Sound       endp
  379.  
  380. Change?      db      0       ;make command line changes permanent?
  381. Dummy3       db      0
  382. StrBytes     dw      0      
  383. Buffer       db      0
  384.  
  385. ;buffer will overwrite the following code
  386.  
  387. Msg    db  10,'ENCORE 1.0 Copyright (c) 1991 Ziff Communications Co.',13,10
  388.        db  'PC Magazine ~ Scott Chaney ~ RSE Inc',13,10,10
  389. Msg0   db  'Syntax: ENCORE [/S] [/L] [/U] [/Kn../Bn../P]',13,10
  390.        db  ' /S  = Save a keystroke sequence to disk',13,10
  391.        db  ' /L  = Load a keystroke sequence (macro)',13,10
  392.        db  ' /U  = Uninstall',13,10
  393. Msg1   db  ' /Kn = Change size of keystroke buffer',13,10
  394.        db  ' /Bn = Change Boost threshold (in clock ticks)',13,10
  395.        db  ' /P  = Make command line changes permanent',13,10
  396. Msg2   db  'Ctrl-R       = Record keystrokes',13,10
  397.        db  'Ctrl-P       = Playback keystrokes',13,10,'$'
  398.     
  399. Already     db  10,'Encore is already loaded',13,10,10,'$'
  400.  
  401. Init        proc
  402.  
  403.             push    cs
  404.             pop     ds
  405.  
  406. ;check for command line
  407.             mov     bx,80h
  408.             mov     cl,[bx]
  409.             cmp     cl,0
  410.             je      P4
  411.  
  412.             mov     si,81h
  413.  
  414. Parse:      mov     al,[si]
  415.             inc     si
  416.             cmp     al,0Dh
  417.             je      P4
  418.             cmp     al,'/'
  419.             je      Parse
  420.             cmp     al,' '
  421.             je      Parse
  422.  
  423.             or      al,20h          ;convert to lower case
  424.  
  425.             cmp     al,'p'          ;make command line changes perm?
  426.             jne     P3      
  427.             mov     Change?,1
  428.  
  429. P3:         cmp     al,'k'          ;change keystroke buffer size?
  430.             jne     P32 ;Parse
  431.  
  432.             call    MakeNum
  433.             mov     bx,5
  434.             mul     bx
  435.             mov     BufSize,ax
  436.             jmp     Parse
  437.  
  438. P32:        cmp     al,'l'          ;load in key file?
  439.             jne     P34
  440.             mov     Ld,1
  441.             jmp     LdSv
  442.  
  443. P34:        cmp     al,'s'          ;save to key file?
  444.             jne     P35
  445.             jmp     LdSv
  446.  
  447. P35:        cmp     al,'b'          ;change boost value?
  448.             jne     P36
  449.             call    MakeNum
  450.             mov     BoostDelay,ax
  451.             jmp     Parse
  452.  
  453. P36:        cmp     al,'u'          ;uninstall?
  454.             jne     Parse
  455.             jmp     UnInstall
  456.  
  457. P4:         call    Loaded?
  458.             jne     P42
  459.  
  460. ;already loaded into memory
  461.             mov     ah,9
  462.             mov     dx,offset Already
  463.             int     21h             ;print 'already loaded'
  464.             mov     Msg1,'$'
  465.             mov     dx,offset Msg0
  466.             mov     ah,9
  467.             int     21h
  468.  
  469.             mov     dx,offset Msg2
  470.             mov     ah,9
  471.             int     21h
  472. Outtahere:  mov     ah,4Ch
  473.             int     21h     ;end
  474.  
  475. ;make command line changes permanent?
  476. P42:        cmp     Change?,1
  477.             jne     P5
  478.             mov     dx,offset FileName
  479.             mov     ax,3D02h
  480.             int     21h             ;open file
  481.             mov     bx,ax           ;file handle
  482.             mov     dx,100h
  483.             mov     cx,7
  484.             mov     ah,40h
  485.             int     21h             ;write 7 bytes to file
  486.             mov     ah,3Eh
  487.             int     21h             ;close file
  488.                                                    
  489. P5:         mov     ah,9
  490.             mov     dx,offset Msg
  491.             int     21h             ;print copyright message
  492.  
  493.             mov     ax,cs:2Ch
  494.             mov     es,ax
  495.             mov     ah,49h
  496.             int     21h             ;free environment memory
  497.            
  498.             mov     ax,3509h
  499.             int     21h             ;get int 09 vector
  500.             mov     word ptr Vec9,BX 
  501.             mov     word ptr Vec9[2],ES
  502.  
  503.             mov     ax,351Ch
  504.             int     21h             ;get int vec 1C
  505.             mov     word ptr Vec1C,bx
  506.             mov     word ptr Vec1C[2],es
  507.  
  508.             mov     word ptr cs:[0100],0
  509.             mov     bx,offset Buffer
  510.             add     bx,BufSize
  511.             mov     EndBuff,bx
  512.             mov     UpperLimit,bx
  513.             mov     cl,4
  514.             shr     bx,cl           ;paragraphs needed
  515.             sub     bx,0Ah          ;less 160 bytes code shifted
  516.  
  517.             push    bx
  518.             mov     si,100h
  519.             mov     cx,offset Buffer
  520.             sub     cx,si
  521.             mov     di,60h
  522.             push    ds
  523.             pop     es
  524.             cld
  525.             rep     movsb           ;mov code down 160 bytes
  526.  
  527.             mov     ax,ds
  528.             sub     ax,0Ah
  529.             mov     ds,ax
  530.             mov     ax,2509h
  531.             mov     dx,offset I9    ;set Int9 vector
  532.             int     21h
  533.  
  534.             mov     ax,251Ch
  535.             mov     dx,offset I1C   ;set Int1C vector
  536.             int     21h
  537.  
  538.             pop     dx
  539.             inc     dx
  540.             MOV     Ax,3100h
  541.             INT     21h             ;terminate and stay resident
  542.  
  543. Init        endp
  544.  
  545. MakeNum     proc
  546. ;converts ASCII number to binary word
  547.             xor     ax,ax
  548.             mov     bx,0Ah
  549. MN1:        mov     cl,[si]
  550.             cmp     cl,'0'
  551.             jb      MN2
  552.             cmp     cl,'9'
  553.             ja      MN2
  554.             mul     bx
  555.             xor     ch,ch
  556.             sub     cl,'0'
  557.             add     ax,cx
  558.             inc     si
  559.             jmp     MN1
  560. MN2:        ret
  561. MakeNum     endp
  562.  
  563. Ld          db      0       ;1 if loading, 0 if saving
  564. ExitMsg     db      13,10,'Encore not loaded',13,10,'$'
  565. NoFile      db      13,10,'File not found',13,10,'$'
  566. NoCreate    db      13,10,'Unable to create file.',13,10,'$'
  567. TooSmall    db      13,10,'Buffer too small',13,10,'$'
  568. Removed     db      13,10,'Encore is uninstalled',13,10,'$'
  569. Ext         db      '.ENC'
  570. FileName    db      'ENCORE.COM',4 dup (0)
  571. StrSize     dw      0
  572.  
  573. LdSv        proc    
  574. ;used to either save a key seq to file, or load a key seq from file 
  575. ;si is already set by Init 
  576.  
  577. ;make filename
  578.             mov     di,offset FileName
  579. LS0:        mov     al,[si]
  580.             inc     si
  581.             cmp     al,0Dh
  582.             je      LS1
  583.             cmp     al,' '
  584.             je      LS0
  585.  
  586.             mov     [di],al
  587.             inc     di
  588.             jmp     LS0
  589.  
  590. LS1:        mov     ax,word ptr Ext 
  591.             mov     [di],ax
  592.             mov     ax, word ptr Ext+2
  593.             mov     [di+2],ax
  594.  
  595.             call    Loaded?
  596.             je      LS2
  597.  
  598. ;Encore not in memory
  599.             mov     dx, offset ExitMsg
  600.             mov     ah,9
  601.             int     21h
  602.             mov     ah,4Ch
  603.             int     21h
  604.  
  605. ;move offset info from TSR into program
  606. LS2:        mov     si,offset BuffOff
  607.             mov     cx,4
  608. LS3:        mov     al,es:[di]
  609.             mov     [si],al
  610.             inc     si
  611.             inc     di
  612.             loop    LS3
  613.  
  614.             mov     dx,offset FileName
  615.             xor     cx,cx
  616.             mov     ax,3D02h
  617.             cmp     Ld,1
  618.             je      LS4
  619.             dec     ah
  620. LS4:        int     21h     ;open filename, or create (if saving)
  621.             jnc     LS6
  622.  
  623. ;unable to open file
  624.             mov     dx,offset NoFile
  625.             cmp     Ld,1
  626.             je      LS5
  627.             mov     dx,offset NoCreate
  628. LS5:        mov     ah,9
  629.             int     21h
  630.             mov     ah,4Ch
  631.             int     21h
  632.  
  633. LS6:        cmp     Ld,1
  634.             jne     LS8
  635.  
  636. ;if loading key sequence from disk
  637.             mov     bx,ax           ;put file handle in bx
  638.             mov     cx,2
  639.             mov     ah,3Fh
  640.             mov     dx,offset StrSize
  641.             int     21h             ;read in StrSize
  642.  
  643. ;check buffer size
  644.             mov     si,BufSizOff
  645.             mov     ax,es:[si]
  646.             cmp     ax,StrSize
  647.             jae     LS7
  648.  
  649. ;not enough room in buffer
  650.             mov     dx,offset TooSmall
  651.             mov     ah,9
  652.             int     21h
  653.             jmp     Endd
  654.  
  655. LS7:        xor     cx,cx
  656.             mov     dx,cx
  657.             mov     ax,4200h
  658.             int     21h     ;move file ptr to beg of file
  659.  
  660.             mov     cx,StrSize
  661.             add     cx,2
  662.             mov     dx,BuffOff
  663.             push    es
  664.             pop     ds
  665.             mov     ah,3Fh
  666.             int     21h     ;read key seq into TSR's buffer
  667.             jmp     Endd
  668.  
  669. ;saving key sequence to disk
  670. LS8:        push    ax              ;file handle
  671.             mov     bx,BuffOff
  672.             mov     cx,es:[bx]      ;size of key sequence 
  673.             mov     dx,bx
  674.             pop     bx
  675.             push    es
  676.             pop     ds
  677.             mov     ah,40h
  678.             int     21h             ;save StrSize and key sequence
  679.  
  680. Endd:       mov     ah,3Eh
  681.             int     21h             ;close file
  682.             mov     ah,4Ch
  683.             int     21h             ;end program
  684.  
  685. LdSv        endp
  686. ;check if already loaded
  687.  
  688. Loaded?     proc
  689. ;checks to see if TSR already is loaded.  If it is then zf set upon 
  690. ;return and es:di points to offset info in TSR
  691.  
  692.             mov     bx,offset Message  
  693.             inc     Message         ;avoid disk cache match
  694.             mov     ax,cs            
  695.             mov     dx,0A000h-1
  696. NextPara:   inc     dx              ;next paragraph
  697.             mov     es,dx
  698.             cmp     dx,ax   
  699.             je      NotHere         ;If our seg then search is done 
  700.             mov     si,bx           ;else check for match
  701.             mov     di,bx              
  702.             mov     cx,0Ah  
  703.             rep     cmpsb           ;a match? 
  704.             jnz     NextPara        ;if no match, keep looking
  705.             ret
  706.  
  707. NotHere:    inc     ax
  708.             cmp     ax,dx           ;return with not equal
  709.             ret
  710.  
  711. Loaded?     endp
  712.  
  713. UnInstall   proc
  714.             call    Loaded?
  715.             jne     U2
  716.  
  717. ;reset interupts to original values
  718.             mov     dx,word ptr es:Vec9
  719.             mov     ax,word ptr es:Vec9[2]
  720.             mov     ds,ax
  721.             mov     ax,2509h
  722.             int     21h             ;reset int 9
  723.             mov     dx,word ptr es:Vec1C
  724.             mov     ax,word ptr es:Vec1C[2]
  725.             mov     ds,ax
  726.             mov     ax,251Ch        ;reset int 1C
  727.             int     21h
  728.             mov     ax,es
  729.             add     ax,0Ah
  730.             mov     es,ax
  731.             mov     ah,49h
  732.             int     21h             ;free memory block
  733.             push    cs
  734.             pop     ds
  735.             mov     dx,offset Removed
  736.             mov     ah,9
  737.             int     21h             ;print message
  738. U2:         mov     ah,4Ch
  739.             int     21h             ;end
  740.    
  741. UnInstall   endp
  742.  
  743. Code        ends
  744.             end     LGo
  745.  
  746.